/**
 * 紧急处理大图片脚本
 * 专门针对最大的几个图片文件进行处理
 */
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');

// 需要紧急处理的大图片列表
const URGENT_IMAGES = [
  'miniprogram/images/news/spring-food.jpg',        // 219.79 KB
  'miniprogram/images/discovers/png/yidalimina.png', // 135.92 KB
  'miniprogram/images/meals/breakfast3.png',         // 123.07 KB
  'miniprogram/images/discovers/png/yumipaigu.png',  // 117.85 KB
  'miniprogram/images/discovers/png/caomeisuannai.png', // 84.87 KB
  'miniprogram/images/meals/dinner3.png',            // 84.78 KB
  'miniprogram/images/discovers/png/xiangguqingcai.png', // 78.17 KB
  'miniprogram/images/discovers/png/kaojixiong.png', // 76.68 KB
  'miniprogram/images/discovers/png/danbaizhinengliangbing.png', // 67.41 KB
  'miniprogram/images/discovers/png/shuiguoshala.png' // 66.12 KB
];

// 设置目标大小上限(KB)
const TARGET_SIZE = 49; // 保守设置在50KB以下

// 创建输出目录
const URGENT_OUTPUT_DIR = 'urgent_fixed_images';
if (!fs.existsSync(URGENT_OUTPUT_DIR)) {
  fs.mkdirSync(URGENT_OUTPUT_DIR);
}

// 创建备份目录
const BACKUP_DIR = 'image_backups';
if (!fs.existsSync(BACKUP_DIR)) {
  fs.mkdirSync(BACKUP_DIR);
}

// 获取文件大小(KB)
function getFileSizeInKB(filePath) {
  try {
    const stats = fs.statSync(filePath);
    return stats.size / 1024;
  } catch (error) {
    console.error(`获取文件大小失败: ${filePath}`, error);
    return 0;
  }
}

// 压缩单个图片
async function compressUrgentImage(imagePath) {
  try {
    // 检查文件是否存在
    if (!fs.existsSync(imagePath)) {
      console.log(`文件不存在: ${imagePath}`);
      return { path: imagePath, status: 'not_found' };
    }

    const fileName = path.basename(imagePath);
    const dirName = path.dirname(imagePath).split(path.sep).pop();
    const outputPath = path.join(URGENT_OUTPUT_DIR, fileName);
    const backupPath = path.join(BACKUP_DIR, `${dirName}_${fileName}`);
    
    // 备份原始文件
    fs.copyFileSync(imagePath, backupPath);
    console.log(`已备份原始文件到: ${backupPath}`);
    
    const originalSize = getFileSizeInKB(imagePath);
    console.log(`处理图片: ${imagePath} (${originalSize.toFixed(2)}KB)`);

    // 获取图片格式
    const ext = path.extname(imagePath).toLowerCase();
    
    // 初始压缩参数
    let quality = 70;
    let width = null;
    
    // 加载图片
    let image = sharp(imagePath);
    const metadata = await image.metadata();
    
    // 如果图片太大，先缩小尺寸
    if (originalSize > 150) {
      width = Math.floor(metadata.width * 0.5); // 缩小为原来的50%
    } else if (originalSize > 100) {
      width = Math.floor(metadata.width * 0.6); // 缩小为原来的60%
    } else if (originalSize > 70) {
      width = Math.floor(metadata.width * 0.7); // 缩小为原来的70%
    } else {
      width = Math.floor(metadata.width * 0.8); // 缩小为原来的80%
    }
    
    console.log(`  原始尺寸: ${metadata.width}x${metadata.height}`);
    console.log(`  目标尺寸: ${width}x${Math.floor(width * metadata.height / metadata.width)}`);
    
    // 调整尺寸
    image = image.resize(width);
    
    // 根据图片类型选择不同的压缩方式
    let buffer;
    if (ext === '.jpg' || ext === '.jpeg') {
      buffer = await image.jpeg({ quality }).toBuffer();
    } else if (ext === '.png') {
      buffer = await image.png({ quality }).toBuffer();
    } else {
      // 对于其他类型，转换为WebP可能更小
      buffer = await image.webp({ quality }).toBuffer();
    }
    
    // 检查压缩后的大小
    let compressedSize = buffer.length / 1024;
    console.log(`  第一次压缩: ${compressedSize.toFixed(2)}KB (质量: ${quality}, 宽度: ${width}px)`);
    
    // 如果还是太大，继续压缩
    let attempts = 1;
    while (compressedSize > TARGET_SIZE && attempts < 5) {
      attempts++;
      
      // 降低质量和尺寸
      quality = Math.max(quality - 10, 40); // 不低于40的质量
      width = Math.floor(width * 0.9);
      
      console.log(`  再次尝试: 质量=${quality}, 宽度=${width}px`);
      
      // 重新调整和压缩
      if (ext === '.jpg' || ext === '.jpeg') {
        buffer = await sharp(imagePath)
          .resize(width)
          .jpeg({ quality })
          .toBuffer();
      } else if (ext === '.png') {
        buffer = await sharp(imagePath)
          .resize(width)
          .png({ quality })
          .toBuffer();
      } else {
        buffer = await sharp(imagePath)
          .resize(width)
          .webp({ quality })
          .toBuffer();
      }
      
      compressedSize = buffer.length / 1024;
      console.log(`  第${attempts}次压缩: ${compressedSize.toFixed(2)}KB`);
    }
    
    // 如果尝试多次后仍然超过目标大小，但已经有明显减少，仍然保存结果
    if (compressedSize > TARGET_SIZE && compressedSize < originalSize * 0.7) {
      console.log(`  警告: 无法压缩到目标大小 ${TARGET_SIZE}KB，但已减少超过30%，保存当前结果`);
    } else if (compressedSize > TARGET_SIZE) {
      // 无法达到目标，尝试转为JPEG
      if (ext !== '.jpg' && ext !== '.jpeg') {
        console.log(`  尝试转换为JPEG格式...`);
        buffer = await sharp(imagePath)
          .resize(width)
          .jpeg({ quality: 60 })
          .toBuffer();
        compressedSize = buffer.length / 1024;
        console.log(`  转换为JPEG后: ${compressedSize.toFixed(2)}KB`);
      }
    }
    
    // 保存压缩后的图片到输出目录
    fs.writeFileSync(outputPath, buffer);
    console.log(`  保存压缩图片到: ${outputPath}`);
    
    // 直接替换原始文件
    fs.writeFileSync(imagePath, buffer);
    console.log(`  直接替换原始文件`);
    
    console.log(`压缩完成: ${originalSize.toFixed(2)}KB -> ${compressedSize.toFixed(2)}KB (${(100 - compressedSize/originalSize*100).toFixed(2)}% 减少)`);
    
    return {
      path: imagePath,
      originalSize,
      newSize: compressedSize,
      reduction: originalSize - compressedSize,
      status: 'success'
    };
  } catch (error) {
    console.error(`处理图片失败: ${imagePath}`, error);
    return {
      path: imagePath,
      error: error.message,
      status: 'error'
    };
  }
}

// 主函数
async function main() {
  console.log('开始紧急处理大图片...');
  
  let totalOriginalSize = 0;
  let totalNewSize = 0;
  let successCount = 0;
  let errorCount = 0;
  let notFoundCount = 0;
  
  // 处理每个紧急图片
  for (const imgPath of URGENT_IMAGES) {
    try {
      const result = await compressUrgentImage(imgPath);
      
      if (result.status === 'success') {
        totalOriginalSize += result.originalSize;
        totalNewSize += result.newSize;
        successCount++;
      } else if (result.status === 'error') {
        errorCount++;
      } else if (result.status === 'not_found') {
        notFoundCount++;
      }
      
      console.log('-'.repeat(50));
    } catch (error) {
      console.error(`处理过程发生错误:`, error);
      errorCount++;
    }
  }
  
  // 打印总结
  console.log('\n紧急图片处理完成!');
  console.log(`总图片数: ${URGENT_IMAGES.length}`);
  console.log(`成功处理: ${successCount}`);
  console.log(`处理失败: ${errorCount}`);
  console.log(`文件不存在: ${notFoundCount}`);
  
  if (successCount > 0) {
    console.log(`\n总体积变化: ${totalOriginalSize.toFixed(2)}KB -> ${totalNewSize.toFixed(2)}KB`);
    console.log(`总减少: ${(totalOriginalSize - totalNewSize).toFixed(2)}KB (${((1 - totalNewSize/totalOriginalSize) * 100).toFixed(2)}%)`);
  }
  
  console.log('\n下一步:');
  console.log('1. 如果处理后的图片质量可以接受，请使用微信开发者工具上传小程序');
  console.log('2. 如果处理后的图片质量不可接受，请考虑将这些图片移至云存储');
  console.log('3. 原始图片已备份在 ' + BACKUP_DIR + ' 目录中');
}

// 执行主函数
main().catch(error => {
  console.error('紧急处理脚本执行失败:', error);
}); 